/**
  ******************************************************************************
  * @author     Chris
  * @since      2024/6/14 22:34
  *
  * @file       hd_led.c
  * @brief      LED Hardware Driver.
  *
  * @note       This file contains the hardware driver for the LED.
  *
  * @warning    The current flowing through the LED cannot exceed 25 mA. It's
  *             better to add a register with LED.
  ******************************************************************************
  * Change Logs:
  *   Date           Author       Notes
  *   2024/6/14     Chris        the first version
  *
  ******************************************************************************
  */

#include <stm32f4xx_ll_gpio.h>
#include "hd_led.h"

static void LED_init_(const LED* this) {
    this->gpio->Mode       = LL_GPIO_MODE_OUTPUT;
    this->gpio->Speed      = LL_GPIO_SPEED_FREQ_VERY_HIGH;
    this->gpio->OutputType = LL_GPIO_OUTPUT_PUSHPULL;
    this->gpio->Pull       = LL_GPIO_PULL_UP;
    this->gpio->Alternate  = LL_GPIO_AF_0;
    GPIO_init(this->gpio);
}

static void LED_on_(const LED* this) {
    this->gpio->GPIOx->BSRR = this->gpio->Pin;
}

static void LED_off_(const LED* this) {
    this->gpio->GPIOx->BSRR = this->gpio->Pin << 16;
}

static void LED_toggle_(const LED* this) {
    LL_GPIO_TogglePin(this->gpio->GPIOx, this->gpio->Pin);
}

void LED_constructor(LED* this, GPIO* gpio) {
    static struct LEDVtbl vtbl = {
        .init   = &LED_init_,
        .on     = &LED_on_,
        .off    = &LED_off_,
        .toggle = &LED_toggle_
    };

    this->vptr = &vtbl;
    this->gpio = gpio;
}
